#include "KKComm.h"
#include "KKUIBase.h"
#include "KKWindow.h"

KKUIBase::KKUIBase(KKUIBase *parent, int width, int height)
{
    // parent
    this->parent = parent;
    if (parent != nullptr)
    {
        parent->addChildren(this);
    }
    // default properties
    auto prop = KKUIProperties("*");
    prop.css[KK_CSS_PROPERTY_LEFT] = {0};
    prop.css[KK_CSS_PROPERTY_TOP] = {0};
    prop.css[KK_CSS_PROPERTY_WIDTH] = {width};
    prop.css[KK_CSS_PROPERTY_HEIGHT] = {height};
    prop.css[KK_CSS_PROPERTY_COLOR] = {KKColor(0, 0, 0, 255)};
    prop.css[KK_CSS_PROPERTY_FONT_SIZE] = {14};
    prop.css[KK_CSS_PROPERTY_PADDING] = {KKSpace(6)};
    prop.css[KK_CSS_PROPERTY_MARGIN] = {KKSpace(0)};
    prop.css[KK_CSS_PROPERTY_BORDER_WIDTH] = {KKSpace(0)};
    prop.css[KK_CSS_PROPERTY_BORDER_COLOR] = {KKSpaceColor(KKColor(0, 0, 0, 255))};
    // initial properties
    properties.push_back(prop);
}

void KKUIBase::onMouseDown(KKPoint pos, KK_MOUSE_BTN btn) {}
void KKUIBase::onMouseUp(KKPoint pos, KK_MOUSE_BTN btn) {}
void KKUIBase::onMouseMove(KKPoint pos) {}
void KKUIBase::onMouseLeave() {}
void KKUIBase::onMouseEnter() {}
void KKUIBase::onMouseWheel(KKPoint pos, int delta) {}
void KKUIBase::onKeyDown(unsigned char key) {}
void KKUIBase::onKeyUp(unsigned char key) {}
void KKUIBase::onKeyChar(unsigned char key) {}
void KKUIBase::onImeChar(wchar_t key) {}
void KKUIBase::onCommand(KKEvent event) {}

void KKUIBase::calcRect(KKRect flexForce)
{
    auto margin = std::get<KKSpace>(properties[0].css[KK_CSS_PROPERTY_MARGIN]);
    auto padding = std::get<KKSpace>(properties[0].css[KK_CSS_PROPERTY_PADDING]);
    auto border_width = std::get<KKSpace>(properties[0].css[KK_CSS_PROPERTY_BORDER_WIDTH]);
    // 计算self rect
    m_rect = flexForce;
    if (this->parent != nullptr)
    {
        m_rect.x1 += this->parent->m_rect.x1;
        m_rect.y1 += this->parent->m_rect.y1;
        m_rect.x2 += this->parent->m_rect.x1;
        m_rect.y2 += this->parent->m_rect.y1;
    }
    m_rect_border = m_rect.sub(margin);
    m_rect_content = m_rect_border.sub(border_width).sub(padding);
}
void KKUIBase::onRender(KKRenderI *render, KKWindow *win)
{
    // render->SetColor(KKColor(255, 0, 0, 255));
    // render->DrawRect(m_rect, false);
    //  Draw all
    auto radius = getProperty<int>(KK_CSS_PROPERTY_BORDER_RADIUS);

    // 背景颜色
    auto bg_color = getProperty<KKColor>(KK_CSS_PROPERTY_BACKGROUND_COLOR);
    if (bg_color.has_value())
    {
        render->SetColor(bg_color.value());
        if (radius.has_value())
        {
            render->DrawRoundRect(m_rect_border, radius.value(), true);
        }
        else
        {
            render->DrawRect(m_rect_border, true);
        }
    }
    // 背景图片
    auto bg_image = getProperty<std::string>(KK_CSS_PROPERTY_BACKGROUND_IMAGE);
    if (bg_image.has_value())
    {
        auto bg_fit = (KK_IMAGE_FIT)getProperty<int>(KK_CSS_PROPERTY_BACKGROUND_REPEAT).value_or(KK_IMAGE_FIT_FILL);
        render->DrawImage(bg_image.value(), m_rect_border, bg_fit);
    }

    // 边框
    auto border_width = getProperty<KKSpace>(KK_CSS_PROPERTY_BORDER_WIDTH).value_or(KKSpace(0));
    if (!border_width.isNull())
    {
        auto color = getProperty<KKSpaceColor>(KK_CSS_PROPERTY_BORDER_COLOR).value_or(KKSpaceColor(KKColor(0, 0, 0, 255)));
        auto line_style = getProperty<KKSpace>(KK_CSS_PROPERTY_BORDER_STYLE).value_or(KKSpace(KK_LINE_STYLE_SOLID));
        render->DrawRect2(m_rect_border, border_width, color, line_style);
    }
    // content
    onRendContent(render, win);
}
void KKUIBase::onRendContent(KKRenderI *render, KKWindow *win)
{
    auto content = getProperty<std::string>(KK_CSS_PROPERTY_CONTENT).value_or("");
    if (content.length() > 0)
    {
        auto align = getProperty<int>(KK_CSS_PROPERTY_TEXT_ALIGN).value_or(0);
        auto color = getProperty<KKColor>(KK_CSS_PROPERTY_COLOR).value_or(KKColor(0, 0, 0, 255));
        // font
        auto font_family = getProperty<std::string>(KK_CSS_PROPERTY_FONT_FAMILY).value_or(render->GetCurFontFamily());
        auto font_size = getProperty<int>(KK_CSS_PROPERTY_FONT_SIZE).value_or(render->GetCurFontSize());
        auto font_style = getProperty<int>(KK_CSS_PROPERTY_FONT_STYLE).value_or(render->GetCurFontStyle());
        render->SetFont(font_family, font_size, font_style);
        render->SetColor(color);
        render->DrawText(content, m_rect_content, (KK_TEXT_ALIGN)align);
    }
}

void KKUIBase::addChildren(KKUIBase *child)
{
    if (std::find(children.begin(), children.end(), child) == children.end())
    {
        children.push_back(child);
    }
}